1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.base;
18
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.common.collect.ImmutableMap;
21 import com.google.common.collect.Maps;
22 import com.google.common.testing.EqualsTester;
23
24 import junit.framework.TestCase;
25
26 import java.io.Serializable;
27 import java.util.Map;
28
29
30
31
32
33
34
35 @GwtCompatible(emulated = true)
36 public class FunctionsTest extends TestCase {
37
38 public void testIdentity_same() {
39 Function<String, String> identity = Functions.identity();
40 assertNull(identity.apply(null));
41 assertSame("foo", identity.apply("foo"));
42 }
43
44 public void testIdentity_notSame() {
45 Function<Long, Long> identity = Functions.identity();
46 assertNotSame(new Long(135135L), identity.apply(new Long(135135L)));
47 }
48
49 public void testToStringFunction_apply() {
50 assertEquals("3", Functions.toStringFunction().apply(3));
51 assertEquals("hiya", Functions.toStringFunction().apply("hiya"));
52 assertEquals("I'm a string",
53 Functions.toStringFunction().apply(
54 new Object() {
55 @Override public String toString() {
56 return "I'm a string";
57 }
58 }));
59 try {
60 Functions.toStringFunction().apply(null);
61 fail("expected NullPointerException");
62 } catch (NullPointerException e) {
63
64 }
65 }
66
67 public void testForMapWithoutDefault() {
68 Map<String, Integer> map = Maps.newHashMap();
69 map.put("One", 1);
70 map.put("Three", 3);
71 map.put("Null", null);
72 Function<String, Integer> function = Functions.forMap(map);
73
74 assertEquals(1, function.apply("One").intValue());
75 assertEquals(3, function.apply("Three").intValue());
76 assertNull(function.apply("Null"));
77
78 try {
79 function.apply("Two");
80 fail();
81 } catch (IllegalArgumentException expected) {
82 }
83
84 new EqualsTester()
85 .addEqualityGroup(function, Functions.forMap(map))
86 .addEqualityGroup(Functions.forMap(map, 42))
87 .testEquals();
88 }
89
90 public void testForMapWithDefault() {
91 Map<String, Integer> map = Maps.newHashMap();
92 map.put("One", 1);
93 map.put("Three", 3);
94 map.put("Null", null);
95 Function<String, Integer> function = Functions.forMap(map, 42);
96
97 assertEquals(1, function.apply("One").intValue());
98 assertEquals(42, function.apply("Two").intValue());
99 assertEquals(3, function.apply("Three").intValue());
100 assertNull(function.apply("Null"));
101
102 new EqualsTester()
103 .addEqualityGroup(function, Functions.forMap(map, 42))
104 .addEqualityGroup(Functions.forMap(map))
105 .addEqualityGroup(Functions.forMap(map, null))
106 .addEqualityGroup(Functions.forMap(map, 43))
107 .testEquals();
108 }
109
110 public void testForMapWithDefault_null() {
111 ImmutableMap<String, Integer> map = ImmutableMap.of("One", 1);
112 Function<String, Integer> function = Functions.forMap(map, null);
113
114 assertEquals((Integer) 1, function.apply("One"));
115 assertNull(function.apply("Two"));
116
117
118 new EqualsTester()
119 .addEqualityGroup(function)
120 .addEqualityGroup(Functions.forMap(map, 1))
121 .testEquals();
122 }
123
124 public void testForMapWildCardWithDefault() {
125 Map<String, Integer> map = Maps.newHashMap();
126 map.put("One", 1);
127 map.put("Three", 3);
128 Number number = Double.valueOf(42);
129 Function<String, Number> function = Functions.forMap(map, number);
130
131 assertEquals(1, function.apply("One").intValue());
132 assertEquals(number, function.apply("Two"));
133 assertEquals(3L, function.apply("Three").longValue());
134 }
135
136 public void testComposition() {
137 Map<String, Integer> mJapaneseToInteger = Maps.newHashMap();
138 mJapaneseToInteger.put("Ichi", 1);
139 mJapaneseToInteger.put("Ni", 2);
140 mJapaneseToInteger.put("San", 3);
141 Function<String, Integer> japaneseToInteger =
142 Functions.forMap(mJapaneseToInteger);
143
144 Map<Integer, String> mIntegerToSpanish = Maps.newHashMap();
145 mIntegerToSpanish.put(1, "Uno");
146 mIntegerToSpanish.put(3, "Tres");
147 mIntegerToSpanish.put(4, "Cuatro");
148 Function<Integer, String> integerToSpanish =
149 Functions.forMap(mIntegerToSpanish);
150
151 Function<String, String> japaneseToSpanish =
152 Functions.compose(integerToSpanish, japaneseToInteger);
153
154 assertEquals("Uno", japaneseToSpanish.apply("Ichi"));
155 try {
156 japaneseToSpanish.apply("Ni");
157 fail();
158 } catch (IllegalArgumentException e) {
159 }
160 assertEquals("Tres", japaneseToSpanish.apply("San"));
161 try {
162 japaneseToSpanish.apply("Shi");
163 fail();
164 } catch (IllegalArgumentException e) {
165 }
166
167 new EqualsTester()
168 .addEqualityGroup(
169 japaneseToSpanish,
170 Functions.compose(integerToSpanish, japaneseToInteger))
171 .addEqualityGroup(japaneseToInteger)
172 .addEqualityGroup(integerToSpanish)
173 .addEqualityGroup(
174 Functions.compose(japaneseToInteger, integerToSpanish))
175 .testEquals();
176 }
177
178 public void testCompositionWildcard() {
179 Map<String, Integer> mapJapaneseToInteger = Maps.newHashMap();
180 Function<String, Integer> japaneseToInteger =
181 Functions.forMap(mapJapaneseToInteger);
182
183 Function<Object, String> numberToSpanish = Functions.constant("Yo no se");
184
185 Function<String, String> japaneseToSpanish =
186 Functions.compose(numberToSpanish, japaneseToInteger);
187 }
188
189 private static class HashCodeFunction implements Function<Object, Integer> {
190 @Override
191 public Integer apply(Object o) {
192 return (o == null) ? 0 : o.hashCode();
193 }
194 }
195
196 public void testComposeOfFunctionsIsAssociative() {
197 Map<Float, String> m = ImmutableMap.of(
198 4.0f, "A", 3.0f, "B", 2.0f, "C", 1.0f, "D");
199 Function<? super Integer, Boolean> h = Functions.constant(Boolean.TRUE);
200 Function<? super String, Integer> g = new HashCodeFunction();
201 Function<Float, String> f = Functions.forMap(m, "F");
202
203 Function<Float, Boolean> c1 = Functions.compose(Functions.compose(h, g), f);
204 Function<Float, Boolean> c2 = Functions.compose(h, Functions.compose(g, f));
205
206
207
208
209
210 assertEquals(c1.hashCode(), c2.hashCode());
211
212 assertEquals(c1.apply(1.0f), c2.apply(1.0f));
213 assertEquals(c1.apply(5.0f), c2.apply(5.0f));
214 }
215
216 public void testComposeOfPredicateAndFunctionIsAssociative() {
217 Map<Float, String> m = ImmutableMap.of(
218 4.0f, "A", 3.0f, "B", 2.0f, "C", 1.0f, "D");
219 Predicate<? super Integer> h = Predicates.equalTo(42);
220 Function<? super String, Integer> g = new HashCodeFunction();
221 Function<Float, String> f = Functions.forMap(m, "F");
222
223 Predicate<Float> p1 = Predicates.compose(Predicates.compose(h, g), f);
224 Predicate<Float> p2 = Predicates.compose(h, Functions.compose(g, f));
225
226
227
228
229
230 assertEquals(p1.hashCode(), p2.hashCode());
231
232 assertEquals(p1.apply(1.0f), p2.apply(1.0f));
233 assertEquals(p1.apply(5.0f), p2.apply(5.0f));
234 }
235
236 public void testForPredicate() {
237 Function<Object, Boolean> alwaysTrue =
238 Functions.forPredicate(Predicates.alwaysTrue());
239 Function<Object, Boolean> alwaysFalse =
240 Functions.forPredicate(Predicates.alwaysFalse());
241
242 assertTrue(alwaysTrue.apply(0));
243 assertFalse(alwaysFalse.apply(0));
244
245 new EqualsTester()
246 .addEqualityGroup(
247 alwaysTrue, Functions.forPredicate(Predicates.alwaysTrue()))
248 .addEqualityGroup(alwaysFalse)
249 .addEqualityGroup(Functions.identity())
250 .testEquals();
251 }
252
253 public void testConstant() {
254 Function<Object, Object> f = Functions.<Object>constant("correct");
255 assertEquals("correct", f.apply(new Object()));
256 assertEquals("correct", f.apply(null));
257
258 Function<Object, String> g = Functions.constant(null);
259 assertEquals(null, g.apply(2));
260 assertEquals(null, g.apply(null));
261
262 new EqualsTester()
263 .addEqualityGroup(f, Functions.constant("correct"))
264 .addEqualityGroup(Functions.constant("incorrect"))
265 .addEqualityGroup(Functions.toStringFunction())
266 .addEqualityGroup(g)
267 .testEquals();
268
269 new EqualsTester()
270 .addEqualityGroup(g, Functions.constant(null))
271 .addEqualityGroup(Functions.constant("incorrect"))
272 .addEqualityGroup(Functions.toStringFunction())
273 .addEqualityGroup(f)
274 .testEquals();
275 }
276
277 private static class CountingSupplier
278 implements Supplier<Integer>, Serializable {
279
280 private static final long serialVersionUID = 0;
281
282 private int value;
283
284 @Override
285 public Integer get() {
286 return ++value;
287 }
288
289 @Override
290 public boolean equals(Object obj) {
291 if (obj instanceof CountingSupplier) {
292 return this.value == ((CountingSupplier) obj).value;
293 }
294 return false;
295 }
296
297 @Override
298 public int hashCode() {
299 return value;
300 }
301 }
302
303 public void testForSupplier() {
304 Supplier<Integer> supplier = new CountingSupplier();
305 Function<Object, Integer> function = Functions.forSupplier(supplier);
306
307 assertEquals(1, (int) function.apply(null));
308 assertEquals(2, (int) function.apply("foo"));
309
310 new EqualsTester()
311 .addEqualityGroup(function, Functions.forSupplier(supplier))
312 .addEqualityGroup(Functions.forSupplier(new CountingSupplier()))
313 .addEqualityGroup(Functions.forSupplier(Suppliers.ofInstance(12)))
314 .addEqualityGroup(Functions.toStringFunction())
315 .testEquals();
316 }
317
318 }
319